package fox.framework.rpc.endpoint.netty.client;

import fox.framework.rpc.client.message.request.RpcClientRequest;
import fox.framework.rpc.common.WebUtils;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;

import java.io.InputStream;
import java.util.Collection;

/**
 * @author cuichao
 * @Description: FoxClientRequestEncoder
 * @Date: create in 2021/1/22 22:12
 */
public class FoxClientRequestEncoder extends MessageToByteEncoder<RpcClientRequest> {

    private static final String PROTOCOL_NAME = "fox";
    private static final int PROTOCOL_MIN_LEN = 2;
    private static final String PROTOCOL_SPILT = "\n";
    private static final String PROTOCOL_ENTRY_SPILT = " ";
    private static final String HEADER_ENTRY_SPILT = ";";
    private static final String HEADER_KV_SPILT = ":";


    @Override
    protected void encode(ChannelHandlerContext ctx, RpcClientRequest request, ByteBuf out) throws Exception {
        String protocol = request.getProtocol();
        if (!PROTOCOL_NAME.equals(protocol)) {
            ctx.fireChannelRead(request);
            return;
        }
        /**
         * encode protocol
         */
        String path = request.getPath();
        String protocol_line = String.format("%s %s", protocol, path) + PROTOCOL_SPILT;
        /**
         * encode header
         */
        Collection<String> headerNames = request.getHeaderNames();
        StringBuilder headerLineBuilder = new StringBuilder();
        for (String headerName : headerNames) {
            headerLineBuilder.append(String.format("%s:%s;", headerName, WebUtils.urlEncode(request.getHeader(headerName))));
        }
        headerLineBuilder.append(PROTOCOL_SPILT);
        String header_line = headerLineBuilder.toString();
        /**
         * write body
         */
        int contentLength = request.getContentLength();
        //encode request body
        InputStream inputStream = request.getInputStream();
        /*
         *write request
         */
        out.writeBytes(protocol_line.getBytes());
        out.writeBytes(header_line.getBytes());
        if(contentLength > 0){
            out.writeBytes(inputStream, contentLength);
        }


    }

}
